package exemplo;

import java.util.Random;

import tabela.TabelaTransacional;
import tabela.ThreadTransacional;
import tabela.Transacao;
import utils.Logger;

/**
 * Thread para executar os experimentos da tabela concorrente em uma transa��o
 * equilibrada: executa X vezes uma opera��o de leitura e uma de escrita em uma
 * posi��o aleat�ria da tabela.
 */
public class TransacaoEquilibradaThread extends ThreadTransacional {
	private static Random random = new Random();

	private TabelaTransacional<Integer, Integer> tabela;

	private int quantidadeOperacoes;

	public TransacaoEquilibradaThread(int id,
			TabelaTransacional<Integer, Integer> tabela, int quantidadeOperacoes) {
		super(id);
		this.tabela = tabela;
		this.quantidadeOperacoes = quantidadeOperacoes;
	}

	protected void doIt() {
		Logger.trace("thread " + id + " iniciando transa��o...");
		Transacao<Integer, Integer> transacao = tabela.iniciaTransacao();
		Logger.trace("thread " + id + " iniciou a transa��o.");

		for (int i = 0; i < quantidadeOperacoes; i++) {
			int chave = random.nextInt(tabela.size());

			Logger.trace("thread " + id + " lendo chave " + chave);

			int valor = tabela.get(transacao, chave);
			
			sleep();
			
			int chaveEscrita = (chave + 1) % tabela.size();

			Logger.trace("thread " + id + " escrevendo na chave " + chaveEscrita
					+ " o valor lido: " + valor);

			tabela.set(transacao, chaveEscrita, valor);

			sleep();
		}

		Logger.trace("thread " + id + " finalizando transa��o...");
		tabela.commitTransacao(transacao);
		Logger.trace("thread " + id + " terminou.");
	}

	private void sleep() {
		try {
			sleep((long) (Math.random() * 10));
		} catch (InterruptedException e) {
		}
	}
}
